#ifndef TC_HSM_HH
#define TC_HSM_HH

/** \file Hsm.hh 
 * Declarations for the class Hsm.
 *
 * (C) Copyright 2003-2006 by Semih Cemiloglu
 * All rights reserved, see COPYRIGHT file for details.
 *
 * $Id: Hsm.hh 116 2006-06-19 06:09:53Z semihc $
 *
 *
 */

#ifndef TC_GLOBAL_HH
# include "Global.hh"
#endif
#ifndef TC_SMIF_HH
# include "SmIf.hh"
#endif


namespace TC {


  class Hsm : public SmIf
  {
  public:
    // TYPES
    typedef SmIf::State_t State_t;
    typedef SmIf::Action_t Action_t;

    // MODIFIERS
    //! Setup HSM, execute initial transition
    void setup(const SmEvent* e = 0);

    //! Dispatch event
    void dispatch(const SmEvent* e);

  protected:
    // CREATORS
    Hsm(State_t st) : SmIf(&Hsm::top), m_source(st) {}
    virtual ~Hsm();
    //! Templated ctor to accept derived classes' actions
    template <typename D>
    Hsm(SmState (D::*mf)(const SmEvent*))
      : SmIf(&Hsm::top), m_source(mf) {}


    // MODIFIERS
    //! The top state: Ultimate root of the state hierarchy
    State_t top(const SmEvent*);

    //! Triggers the action of of a given state by sending to it
    //! a given signal.
    State_t trigger(State_t st, SmSignal_t sig);

    //! Initial state transition in a composite state.
    void init(State_t st) { m_state = st; }

    //! State transition to a target state.
    void tran(State_t target);

    // ACCESSORS
    //! Templated tran() to accept derived classes' actions
    template <typename D>
    void tran(SmState (D::*mf)(const SmEvent*))
    {
      Action_t act;
      CastToSmAction(act,mf);
      tran(State_t(act));
    }
    

  private:
    // NOT ALLOWED
    Hsm();
    Hsm(const Hsm&);
    void operator=(const Hsm&);

    // MEMBERS
    //! Source state during a transition.
    //! If the transition is inherited from a superstate, the 
    //! source of this transition will be different from the active state.
    State_t m_source;

  }; // end class


} // end namespace




#endif /* TC_HSM_HH */
